/**
 * Copyright (c) 2024 - CARThunder
 * All Rights Reserved by Chengdu CARThunder Intelligent Technology Co., LTD and its affiliates.
 * You may not use, copy, distribute, modify, transmit in any form this file
 * except in compliance with CARThunder in writing by applicable law.
 *
 */

/**
 * file description.
 * @file    filename
 * @brief   brief function description.
 * @details detailed function description.
 * @version 1.0
 * @author  author_name
 * @date    last_modified_date
 *
 *      Edit History
 *      ----------------------------------------------------------------------------
 *      DATE                     NAME               DESCRIPTION
 *      2024-07-30              zhihuazhang         Create it.
 *
 */


package com.cart.musicdemo.base.service;

import android.media.MediaPlayer;
import android.util.Log;
import android.widget.TextView;

import com.cart.musicdemo.base.impl.MusicPlayerListener;
import com.cart.musicdemo.base.utils.FileUtils;
import com.cart.musicdemo.base.utils.TimeUtils;
import com.cart.musicdemo.model.SongModel;


/**
 * The type Music player service.
 */
public class MusicPlayerManager implements MediaPlayer.OnBufferingUpdateListener,
        MediaPlayer.OnPreparedListener, MediaPlayer.OnCompletionListener {

    static {
        TAG = MusicPlayerManager.class.getName();
        DEFAULT_LISTENER = new MusicPlayerListener() {
            @Override
            public void onPlay() {
                Log.d(TAG, "歌曲开始播放");
            }

            @Override
            public void onPause() {
                Log.d(TAG, "歌曲已暂停");
            }

            @Override
            public void onStop() {
                Log.d(TAG, "歌曲已中断");
            }
        };
    }

    private static volatile MusicPlayerManager instance;

    private MusicPlayerListener listener;
    //android原生媒体播放
    private final MediaPlayer mediaPlayer;

    private static final String TAG;

    private static final MusicPlayerListener DEFAULT_LISTENER;

    private String lastPlayedHash;

    private MediaPlayer.OnCompletionListener onCompletionListener;

    private ProgressBarHandler progressBarHandler;

    private TextView text;

    private static final int MESSAGE = 1;

    private SongModel songModel;

    /**
     * Gets instance.
     *
     * @return the instance
     */
    public static MusicPlayerManager getInstance() {
        return getInstance(null);
    }

    /**
     * Gets instance.
     *
     * @param listener the listener
     * @return the instance
     */
    public static MusicPlayerManager getInstance(MusicPlayerListener listener) {
        if (instance == null) {
            synchronized (MusicPlayerManager.class) {
                if (instance == null) {
                    instance = new MusicPlayerManager(listener);
                }
            }
        }
        return instance;
    }

    /**
     * init MusicPlayerManager.
     *
     * @param listener onclick
     */
    private MusicPlayerManager(MusicPlayerListener listener) {
        // 初始化 MediaPlayer
        mediaPlayer = new MediaPlayer();
        // listener为空时提供默认接口实现
        if (listener == null) {
            setListener(DEFAULT_LISTENER);
        } else {
            setListener(listener);
        }
        // 设置监听器
        mediaPlayer.setOnBufferingUpdateListener(this);
        mediaPlayer.setOnPreparedListener(this);
        mediaPlayer.setOnCompletionListener(this);
    }

    /**
     * Init.
     *
     * @param progressBarHandler the progress bar handler
     * @param text               the text
     */
    public void init(ProgressBarHandler progressBarHandler, TextView text) {
        progressBarHandler.setMusicPlayerService(this);
        this.progressBarHandler = progressBarHandler;
        this.text = text;
    }

    /**
     * Init media seek on.
     *
     * @param path     the path
     * @param position the position
     */
    public void initMediaSeekOn(String path, int position) {
        lastPlayedHash = FileUtils.calculateFileHash(path);
        initMediaResource(path);
        mediaPlayer.seekTo(position);
        playInternal();
    }

    /**
     * Play.
     *
     * @param songModel the song model
     */
    public void play(SongModel songModel) {
        // 对比MD5值，如果是已经在播放的音乐则接着播放
        String currentHash = FileUtils.calculateFileHash(songModel.getPath());
        if (currentHash.equals(lastPlayedHash)) {
            playInternal();
        } else {
            this.songModel = songModel;
            lastPlayedHash = currentHash;
            initMediaResource(songModel.getPath());
            playInternal();
        }
        progressBarHandler.sendEmptyMessage(MESSAGE);
    }

    private void playInternal() {
        mediaPlayer.start();
        notifyPlay();
    }

    /**
     * initMediaResource.
     *
     * @param musicFilePath path
     */
    private void initMediaResource(String musicFilePath) {
        try {
            mediaPlayer.reset();
            mediaPlayer.setDataSource(musicFilePath);
            mediaPlayer.prepare();
        } catch (Exception exception) {
            // todo:后期采用更高级的日志系统，可能会发生文件不存在等情况
            exception.printStackTrace();
        }
    }

    /**
     * Pause.
     */
    public void pause() {
        if (mediaPlayer.isPlaying()) {
            mediaPlayer.pause();
            notifyPause();
        }
        progressBarHandler.removeMessages(MESSAGE);
    }

    /**
     * Stop.
     */
    public void stop() {
        if (mediaPlayer.isPlaying()) {
            mediaPlayer.stop();
            mediaPlayer.reset();
            lastPlayedHash = null; // 让音乐能够重新被加载
            progressBarHandler.setProgress(0);
            progressBarHandler.removeMessages(MESSAGE);
            notifyStop();
        }
    }

    /**
     * Destroy.
     */
    public void destroy() {
        mediaPlayer.release();
        progressBarHandler.removeCallbacksAndMessages(null);
    }

    /**
     * Gets current playing info.
     *
     * @param currentTime the current time
     * @param maxTime     the max time
     * @return the current playing info
     */
    public String getCurrentPlayingInfo(int currentTime, int maxTime) {
        String info = String.format("正在播放:  %s\t\t", songModel.getName());
        return String.format("%s %s / %s", info, TimeUtils.formatTime(currentTime),
                TimeUtils.formatTime(maxTime));
    }

    /**
     * Is playing boolean.
     *
     * @return the boolean
     */
    public Boolean isPlaying() {
        return mediaPlayer.isPlaying();
    }

    /**
     * Sets progress bar handler.
     *
     * @param progressBarHandler the progress bar handler
     */
    public void setProgressBarHandler(ProgressBarHandler progressBarHandler) {
        this.progressBarHandler = progressBarHandler;
    }

    /**
     * Sets on completion listener.
     *
     * @param listener the listener
     */
    public void setOnCompletionListener(MediaPlayer.OnCompletionListener listener) {
        this.onCompletionListener = listener;
    }

    private void setListener(MusicPlayerListener listener) {
        this.listener = listener;
    }

    private void notifyPlay() {
        if (listener != null) {
            listener.onPlay();
        }
    }

    private void notifyPause() {
        if (listener != null) {
            listener.onPause();
        }
    }

    private void notifyStop() {
        if (listener != null) {
            listener.onStop();
        }
    }


    /**
     * Gets media player.
     *
     * @return the media player
     */
    public MediaPlayer getMediaPlayer() {
        return mediaPlayer;
    }

    /**
     * Gets text.
     *
     * @return the text
     */
    public TextView getText() {
        return text;
    }

    /**
     * Sets text.
     *
     * @param text the text
     */
    public void setText(TextView text) {
        this.text = text;
    }

    @Override
    public void onBufferingUpdate(MediaPlayer mp, int percent) {
        progressBarHandler.setSecondaryProgress(percent);
        Log.e(TAG, mediaPlayer.getCurrentPosition() + "% play --> " + percent + "% buffer");
    }

    @Override
    public void onCompletion(MediaPlayer mp) {
        Log.e(TAG, "onCompletion");
        if (onCompletionListener != null) {
            onCompletionListener.onCompletion(mp);
        }
    }

    @Override
    public void onPrepared(MediaPlayer mp) {
        Log.e(TAG, "onPrepared");
        mp.start();
    }
}
